<?php 
class Main_Db_Adapter_Pgsql extends Main_Db_Adapter_Abstract
{
	const FETCH_ASSOC = PGSQL_ASSOC; //1
	
	const FETCH_NUM	= PGSQL_NUM; //2 
	
	const FETCH_BOTH = PGSQL_BOTH; //3 
	
	/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#_connect()
	 */
	protected function _connect()
	{
		$connection_string = ' host=' . $this->options['host']
						   . ' port='.$this->options['port']
						   . ' dbname='.$this->options['dbname']
					       . ' user='.$this->options['username']
					       . ' password='.$this->options['password'];
					
		
		if (! $this->_connection = pg_pconnect($connection_string) ) {
			return false;
		}		

		$this->_fetchMode = self::FETCH_ASSOC;

		$encoding = Zend_Registry::getInstance()->encoding;
		
		pg_set_client_encoding($this->_connection, $encoding);
	
		return true;
	}
	
	/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#closeConnection()
	 */
	public function closeConnection()
	{
		$result = ((bool) pg_close($this->_connection));
		parent::closeConnection();
		return $result;
	}
	
	/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#query()
	 */
	public function query($sql) 
	{
		if (! $this->isConnected()) {
			$this->_connect();
		}
		$result = pg_query($this->_connection, $sql);
		if (false === $result) {
			throw new Exception("Invalid query: {$sql}. Error:" . pg_last_error());
		} else {
			return $result;
		}
	}
	
/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#fetchAll()
	 */
	public function fetchAll($sql, $fetchMode = null)
	{
		$list = array();
		if (null === $fetchMode) {
            $fetchMode = $this->_fetchMode;
        }

        while ($row = pg_fetch_array($result, null, $fetchMode)) {
			$list[] = $row;
		}
		return $list;
	}
	
	/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#fetchAllLimited()
	 */
 	public function fetchAllLimited($sql, $limit, $offset, $fetchMode = null)
 	{
 		$sql .= (($limit===false)?'':(' LIMIT ').(int)$limit)
			 . (($offset===false)?'':(' OFFSET ').(int)$offset);
 		
 		return $this->fetchAll($sql, $fetchMode);
 	}
	
	/**
 	 * (non-PHPdoc)
 	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#fetchRow()
 	 */
	public function fetchRow($sql, $fetchMode = null)
	{
		if (null === $fetchMode) {
            $fetchMode = $this->_fetchMode;
        }
        $result = $this->query($sql);
		if ($row = pg_fetch_array($result, null, $fetchMode)) {
			return $row;
		} else {
			return array();		
		}
	}
	
	/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#fetchAllLimited()
	 */
 	public function fetchRowLimited($sql, $limit, $offset, $fetchMode = null)
 	{
 		$sql .= (($limit===false)?'':(' LIMIT ').(int)$limit)
			 . (($offset===false)?'':(' OFFSET ').(int)$offset);
 		
 		return $this->fetchRow($sql, $fetchMode);
 	}
 	
	/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#fetchOne()
	 */
	public function fetchOne($sql)
	{
        $result = $this->query($sql);
		if ($row = pg_fetch_row($result)) {
			return $row[0];
		} else {
			return null;		
		}
	}
	
	/**
	 * (non-PHPdoc)
	 * @see library/Main/Db/Adapter/Main_Db_Adapter_Abstract#lastInsertId()
	 */
	public function lastInsertId($sequence)
	{
		$id = $this->fetchOne("SELECT currval('".$sequence."')");
		return $id;
	}
	
}